<template>
  <div>
    <input type="text" v-model.number="k">
    <div id="main" style="width: 800px;height:600px;" ref="echarts"></div>
  </div>

</template>

<script>
import KMeans from '../../node_modules/tf-kmeans/dist/index.js'
import * as tf from '@tensorflow/tfjs'
import * as d3 from "d3";
export default {
  watch:{
    k(oldValue,newValue){
      if(oldValue!=""){
        var chart =this.$echarts.getInstanceByDom(this.$refs.echarts)
        chart.clear();
        this.echartsConstruct();
      }
    }
  },
  data() {
    return {
        k: 1, 
    }
  },
  methods: {
    kmeansConstruct(data){
      const option = {
        k: this.k, //选取的k的点数
        maxIter: 100, //最大的项数
        distanceFunction: KMeans.EuclideanDistance //KMeans的默认方法
      }
      const kmeans = new KMeans(option);
      const dataset = tf.tensor(data);
      const predictions = kmeans.Train(
        dataset
      );
      var data=kmeans.Centroids().arraySync()
      var assignedTo=predictions.arraySync();
      for(var i=0;i<data.length;i++){
        var pointArray=data[i];
        for(var j=0;j<pointArray.length;j++){
          var axis=pointArray[j].toFixed(2);
          data[i][j]=axis;
        }
      }
      //console.log("Assigned To ", predictions.arraySync()); //分配的点指定到那一簇
      //console.log("Centroids Used are ", data);  //簇的中心点。
      return {data,assignedTo};
    },
    echartsConstruct: async function () {
      var myChart = this.$echarts.init(this.$refs.echarts);
      var data = await this.getData();
      this.$emit("data", data);
      var option = this.echarset(data);
      myChart.setOption(option);
    },
    getData: async function () {
      var i = 0;
      var setosa = [];
      var versicolor = [];
      var virginica = [];
      var petal_length = [];
      await d3.csv("./鸢尾花/iris.csv", function (data, error) {
        petal_length.push(parseFloat(data["PetalLength"]));
        if (i < 50) {
          setosa[i] = [parseFloat(data["PetalLength"]), parseFloat(data["PetalWidth"])];
        }
        else if (i >= 100) {
          versicolor[i - 100] = [parseFloat(data["PetalLength"]), parseFloat(data["PetalWidth"])];
        }
        else {
          virginica[i - 50] = [parseFloat(data["PetalLength"]), parseFloat(data["PetalWidth"])];
        }
        i++;
      });
      var setosa_mean = d3.mean(petal_length.slice(0, 50));
      var versicolor_mean = d3.mean(petal_length.slice(50, 100));
      var virginica_mean = d3.mean(petal_length.slice(100, 150));
      // console.table([setosa_mean, versicolor_mean, virginica_mean]);
      return { setosa, versicolor, virginica, petal_length, setosa_mean, versicolor_mean, virginica_mean }
    },
    serieCreated(data,color){
      var serie={
          color,
          name: 'Female',
          type: 'scatter',
          emphasis: {
            focus: 'series'
          },
          data,
          markArea: {
              silent: true,
              itemStyle: {
                color: 'transparent',
                borderWidth: 1,
                borderType: 'dashed'
              },
              data: [[{
                // name: 'setosa Data Range',
                xAxis: 'min',
                yAxis: 'min'
              }, {
                xAxis: 'max',
                yAxis: 'max'
              }]]
            },
      };
      return serie;
    },
    assignedToSeries(assignedTo,data,k,group){
      var series=[];
      var colors=["#ee6666","#3ba272","#fc8452","#9a60b4","#ea7ccc","#5470c6"]
      for(var i=0;i<k;i++){
        var dataPoint=[]
        for(var j=0;j<assignedTo.length;j++){
          if(assignedTo[j]==i) dataPoint.push(data[j])
        }
        var colorindex=i+group*this.k%colors.length;
        series.push(this.serieCreated(dataPoint,colors[colorindex]));
      }
      return series;
    },
    echarset:function(data) {
      var { setosa, versicolor, virginica, petal_length, setosa_mean, versicolor_mean, virginica_mean } = data;

      var {data:setosa_Point,assignedTo:setosa_assignedTo}=this.kmeansConstruct(setosa);
      var {data:versicolor_Point,assignedTo:versicolor_assignedTo}=this.kmeansConstruct(versicolor);
      var {data:virginica_Point,assignedTo:virginica_assignedTo}=this.kmeansConstruct(virginica);
      var group=1;
      var setosa_Series=this.assignedToSeries(setosa_assignedTo,setosa,this.k,group)
      var versicolor_Series=this.assignedToSeries(versicolor_assignedTo,versicolor,this.k,group++);
      var virginica_Series=this.assignedToSeries(virginica_assignedTo,virginica,this.k,group++);
      var option = {
        title: {
          text: '鸢尾花数据可视化'
        },

        grid: {
          left: '3%',
          right: '7%',
          bottom: '7%',
          containLabel: true
        },
        tooltip: {
          showDelay: 0,
          formatter: function (params) {
            if (params.value.length > 1) {
              return params.seriesName + ' :<br/>'
                + params.value[0] + 'cm '
                + params.value[1] + 'cm ';
            }
            else {
              return params.seriesName + ' :<br/>'
                + params.name + ' : '
                + params.value + 'cm ';
            }
          },
          axisPointer: {
            show: true,
            type: 'cross',
            lineStyle: {
              type: 'dashed',
              width: 1
            }
          }
        },

        toolbox: {
          feature: {
            dataZoom: {},
            brush: {
              type: ['rect', 'polygon', 'clear']
            }
          }
        },
        brush: {
        },

        legend: {
          data: ['setosa', 'versicolor', 'virginica'],
          left: 'center',
          bottom: 10
        },

        xAxis: [
          {
            type: 'value',
            scale: true,
            axisLabel: {
              formatter: '{value} cm'
            },
            splitLine: {
              show: false
            }
          }
        ],

        yAxis: [
          {
            type: 'value',
            scale: true,
            axisLabel: {
              formatter: '{value} cm'
            },
            splitLine: {
              show: false
            }
          }
        ],
        series: [
          {
            color:"black",
            name: 'Center',
            type: 'scatter',
            emphasis: {
              focus: 'series'
            },
            data: setosa_Point,
            symbolSize:13,
          },
          {
            color:"blue",
            name: 'Center',
            type: 'scatter',
            emphasis: {
              focus: 'series'
            },
            data: versicolor_Point,
            symbolSize:13,
          },
          {
            color:"#73c0de",
            name: 'Center',
            type: 'scatter',
            emphasis: {
              focus: 'series'
            },
            data: virginica_Point,
            symbolSize:13,
          },
          {
            name: 'Female',
            type: 'scatter',
            emphasis: {
              focus: 'series'
            },
            data: setosa,
            markArea: {
              silent: true,
              itemStyle: {
                color: 'transparent',
                borderWidth: 1,
                borderType: 'dashed'
              },
              data: [[{
                name: 'setosa Data Range',
                xAxis: 'min',
                yAxis: 'min'
              }, {
                xAxis: 'max',
                yAxis: 'max'
              }]]
            },
            // markPoint: {
            //   data: [
            //     { type: 'max', name: 'Max' },
            //     { type: 'min', name: 'Min' }
            //   ]
            // },
            // markLine: {
            //   lineStyle: {
            //     type: 'solid'
            //   },
            //   data: [
            //     { type: 'average', name: '平均值' },
            //     { xAxis: setosa_mean }
            //   ]
            // }
          }, {
            color: "#fac857",
            name: 'Female',
            type: 'scatter',
            emphasis: {
              focus: 'series'
            },
            data: virginica,
            markArea: {
              silent: true,
              itemStyle: {
                color: 'transparent',
                borderWidth: 1,
                borderType: 'dashed'
              },
              data: [[{
                name: 'virginica Data Range',
                xAxis: 'min',
                yAxis: 'min'
              }, {
                xAxis: 'max',
                yAxis: 'max'
              }]]
            },
            // markPoint: {
            //   data: [
            //     { type: 'max', name: 'Max' },
            //     { type: 'min', name: 'Min' }
            //   ]
            // },
            // markLine: {
            //   lineStyle: {
            //     type: 'solid'
            //   },
            //   data: [
            //     { type: 'average', name: '平均值' },
            //     { xAxis: versicolor_mean }
            //   ]
            // }
          }, {
            color: "#a7d691",
            name: 'Female',
            type: 'scatter',
            emphasis: {
              focus: 'series'
            },
            data: versicolor,
            markArea: {
              silent: true,
              itemStyle: {
                color: 'transparent',
                borderWidth: 1,
                borderType: 'dashed'
              },
              data: [[{
                name: 'versicolor Data Range',
                xAxis: 'min',
                yAxis: 'min',

              }, {
                xAxis: 'max',
                yAxis: 'max'
              }]]
            },
            // markPoint: {
            //   data: [
            //     { type: 'max', name: 'Max' },
            //     { type: 'min', name: 'Min' }
            //   ]
            // },
            // markLine: {
            //   lineStyle: {
            //     type: 'solid'
            //   },
            //   data: [
            //     { type: 'average', name: '平均值' },
            //     { xAxis: virginica_mean }
            //   ]
            // }
          }
        ]
      }
      option.series=option.series.concat(setosa_Series);
      option.series=option.series.concat(versicolor_Series);
      option.series=option.series.concat(virginica_Series);
      return option;
    }
  },
  mounted() {
    this.echartsConstruct();
  },
}
</script>

<style lang="less" scoped></style>
